package com.ext.aic.handler;

import android.content.Context;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.TextWatcher;
import android.text.method.ArrowKeyMovementMethod;
import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;

import com.ext.aic.components.MarkdownParser;
import com.ext.aic.components.RectCornerSpan;
import com.eyinfo.android_pure_utils.ObjectManager;
import com.eyinfo.android_pure_utils.utils.PixelUtils;
import com.onegravity.rteditor.RTEditText;

public class EditSpanHandler {

    private String content;

    //step1
    public SpannableString buildSpannableString(RTEditText editRte, String content) {
        this.content = content;
        int start = Math.max(editRte.getSelectionStart(), 0);
        String text = editRte.getText().toString();
        int end = text.length();
        SpannableStringBuilder builder = MarkdownParser.parse(content);
        builder.append(start == end ? "\n" : " ");
        return new SpannableString(builder.toString());
    }

    //step2
    public RectCornerSpan buildAiGenerateSpan(Context context) {
        int screenWidth = ObjectManager.getScreenWidth(context);
        int maxWidth = PixelUtils.px2dip(context, screenWidth) - 24;
        return new RectCornerSpan(content, 0xFFEDF6FC, 0xFF3FB2FF, 12, 16, 16, maxWidth, 18);
    }

    //step3
    public void bindSpan(SpannableString spannableString, RectCornerSpan aiGenerateSpan) {
        spannableString.setSpan(aiGenerateSpan, 0, spannableString.length() - 1, SpannableString.SPAN_EXCLUSIVE_INCLUSIVE);
    }

    //step4
    public void insertEdit(RTEditText editRte, SpannableString spannableString) {
        int start = Math.max(editRte.getSelectionStart(), 0);
        int end = Math.max(editRte.getSelectionEnd(), 0);
        editRte.getText().replace(start, end, spannableString);
        editRte.setSelection(start + spannableString.length());
        editRte.requestFocus();
        content = "";
    }

    private void fitCurrentCursor(RTEditText editRte, Editable editable, int cursorPos, int spanStart, int spanEnd) {
        int newPos;
        if (cursorPos == spanStart) {
            newPos = Math.max(0, spanStart - 1);
        } else {
            newPos = Math.min(spanEnd + 1, editable.length());
        }
        if (newPos >= 0 && newPos <= editable.length()) {
            editRte.setSelection(newPos);
        }
    }

    private boolean fitCursorPosition(RTEditText editRte) {
        int cursorPos = editRte.getSelectionStart();
        Editable editable = editRte.getText();
        RectCornerSpan[] spans = editable.getSpans(cursorPos, cursorPos, RectCornerSpan.class);
        if (spans == null) {
            return false;
        }
        // 如果光标在 Span 的起始或结束边界，调整位置
        for (RectCornerSpan span : spans) {
            int spanStart = editable.getSpanStart(span);
            int spanEnd = editable.getSpanEnd(span);
            // 移动光标到Span外部
            if (cursorPos == spanStart) {
                int startPosition = Math.max(0, spanStart);
                editRte.setSelection(startPosition);
                return false;
            } else if (cursorPos == spanEnd) {
                int endPosition = Math.min(spanEnd + 1, editable.length());
                editRte.setSelection(endPosition);
                return true;
            }
        }
        return false;
    }

    public void fitCursor(RTEditText editRte) {
        editRte.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_DEL) {
                    Boolean status = fitDelete(editRte, keyCode, event);
                    if (status == null) {
                        return false;
                    }
                    return status;
                } else if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    replaceNewlineWithSpace(editRte.getText());
                }
                return true;
            }
        });
        editRte.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                fitCursorPosition(editRte);
            }
        });
        editRte.addTextChangedListener(new TextWatcher() {
            private boolean isReplacing = false;

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                fitCursorPosition(editRte);
                if (isReplacing) {
                    return;
                }
            }
        });
        editRte.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    fitCursorPosition(editRte);
                }
            }
        });
        editRte.setMovementMethod(new ArrowKeyMovementMethod() {
            @Override
            public boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode, int movementMetaState, KeyEvent event) {
                // 1. 先调用父类方法处理默认方向键逻辑
                boolean handled = super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);
                // 2. 如果父类已处理，检查是否需要调整光标位置
                if (handled) {
                    int cursorPosition = widget.getSelectionStart();
                    RectCornerSpan[] spans = buffer.getSpans(cursorPosition, cursorPosition, RectCornerSpan.class);
                    if (spans == null) {
                        return handled;
                    }
                    for (RectCornerSpan span : spans) {
                        int spanStart = buffer.getSpanStart(span);
                        int spanEnd = buffer.getSpanEnd(span);
                        // 3. 如果光标恰好在 Span 的边界，移动光标避开
                        if (cursorPosition == spanStart || cursorPosition == spanEnd) {
                            int newPosition = (cursorPosition == spanStart) ? spanStart - 1 : spanEnd + 1;
                            newPosition = Math.max(0, Math.min(newPosition, buffer.length()));
                            Selection.setSelection(buffer, newPosition);
                            break;
                        }
                    }
                }
                return handled;
            }
        });
    }

    private void replaceNewlineWithSpace(Editable editable) {
        int cursorPosition = Selection.getSelectionStart(editable);
        if (cursorPosition <= 0) {
            return;
        }
        editable.replace(cursorPosition - 1, cursorPosition, " ");
        // 恢复光标到原位置（因为替换后光标会移动到空格后）
        Selection.setSelection(editable, cursorPosition);
    }

    public Boolean fitDelete(RTEditText editRte, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_DEL) {
            int selectionStart = editRte.getSelectionStart();
            int selectionEnd = editRte.getSelectionEnd();
            if (selectionStart == selectionEnd) {
                Editable editable = editRte.getText();
                RectCornerSpan[] spans = editable.getSpans(selectionStart, selectionStart, RectCornerSpan.class);
                for (RectCornerSpan span : spans) {
                    int spanStart = editable.getSpanStart(span);
                    int spanEnd = editable.getSpanEnd(span);
                    if (selectionStart == spanEnd) {
                        // 当光标在 Span 结束位置，删除 Span
                        editable.removeSpan(span);
                        editable.delete(spanStart, spanEnd);
                        editRte.setSelection(spanStart);
                        return true;
                    }
                }
            }
        }
        return null;
    }
}
